/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.fzhucc.modules.thinktank.service;

import com.fzhucc.exception.BadRequestException;
import com.fzhucc.modules.pms.domain.Project;
import com.fzhucc.modules.pms.domain.dto.ProjectDto;
import com.fzhucc.modules.pms.domain.dto.ProjectExpertScoreDto;
import com.fzhucc.modules.pms.repository.ProjectRepository;
import com.fzhucc.modules.pms.service.ProjectService;
import com.fzhucc.modules.thinktank.domain.Company;
import com.fzhucc.modules.thinktank.domain.CompanyProjectLog;
import com.fzhucc.modules.thinktank.domain.Leader;
import com.fzhucc.modules.thinktank.domain.LeaderProjectLog;
import com.fzhucc.modules.thinktank.domain.dto.CompanyProjectDistributionDto;
import com.fzhucc.modules.thinktank.domain.dto.LeaderProjectDistributionDto;
import com.fzhucc.modules.thinktank.repository.LeaderRepository;
import com.fzhucc.utils.*;
import lombok.RequiredArgsConstructor;
import com.fzhucc.modules.thinktank.repository.LeaderProjectLogRepository;
import com.fzhucc.modules.thinktank.domain.dto.LeaderProjectLogDto;
import com.fzhucc.modules.thinktank.domain.dto.LeaderProjectLogQueryCriteria;
import com.fzhucc.modules.thinktank.service.mapstruct.LeaderProjectLogMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author yyg
* @date 2023-01-03
**/
@Service
@RequiredArgsConstructor
public class LeaderProjectLogService {

    private final LeaderProjectLogRepository leaderProjectLogRepository;
    private final LeaderProjectLogMapper leaderProjectLogMapper;

    private final LeaderRepository leaderRepository;

    private final ProjectRepository projectRepository;

    private final ProjectService projectService;

    public Map<String,Object> queryAll(LeaderProjectLogQueryCriteria criteria, Pageable pageable){
        Page<LeaderProjectLog> page = leaderProjectLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(leaderProjectLogMapper::toDto));
    }

    public List<LeaderProjectLogDto> queryAll(LeaderProjectLogQueryCriteria criteria){
        return leaderProjectLogMapper.toDto(leaderProjectLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    public LeaderProjectLogDto findById(Integer id) {
        LeaderProjectLog leaderProjectLog = leaderProjectLogRepository.findById(id).orElseGet(LeaderProjectLog::new);
        ValidationUtil.isNull(leaderProjectLog.getId(),"LeaderProjectLog","id",id);
        return leaderProjectLogMapper.toDto(leaderProjectLog);
    }

    @Transactional(rollbackFor = Exception.class)
    public LeaderProjectLogDto create(LeaderProjectLog resources) {
        return leaderProjectLogMapper.toDto(leaderProjectLogRepository.save(resources));
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(LeaderProjectLog resources) {
        LeaderProjectLog leaderProjectLog = leaderProjectLogRepository.findById(resources.getId()).orElseGet(LeaderProjectLog::new);
        ValidationUtil.isNull( leaderProjectLog.getId(),"LeaderProjectLog","id",resources.getId());
        leaderProjectLog.copy(resources);
        leaderProjectLogRepository.save(leaderProjectLog);
    }

    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            leaderProjectLogRepository.deleteById(id);
        }
    }

    public void download(List<LeaderProjectLogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (LeaderProjectLogDto leaderProjectLog : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("分配时间", leaderProjectLog.getRelationTime());
            map.put("产业龙头id", leaderProjectLog.getLeaderId());
            map.put("项目id", leaderProjectLog.getProjectId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    public List<Long> getDifferenceSet(List<Long> allList, List<Long> list) {
        List<Long> resultList = new ArrayList<>();
        Map<String, Long> map = new HashMap<>();
        list.forEach(i2 -> {
            map.put(i2 + "", i2);
        });
        allList.forEach(i1 -> {
            Long m = map.get(i1 + "");
            //如果为空，则证明list2中无该数据
            if (m == null) {
                resultList.add(i1);
            }
        });
        return resultList;
    }

    @Transactional
    public void dodistribution(LeaderProjectDistributionDto leaderProjectDistributionDto) {
        String project_id = leaderProjectDistributionDto.getProjectId();
        List<Long> list = leaderProjectDistributionDto.getListLeaderId();
        List<Long> repeatlist = new ArrayList<Long>();
        Optional<Project> optionalProject = projectRepository.findById(project_id);
        if (optionalProject.isEmpty()) {
            throw new BadRequestException("项目未找到");
        }
        if (list == null) {
            throw new BadRequestException("产业龙头id list未找到");
        }
        //先删除所有该项目的绑定的产业龙头
        List<LeaderProjectLog> listLeaderProjectLog = leaderProjectLogRepository.findByProjectId(project_id);
        for (LeaderProjectLog leaderProjectLog : listLeaderProjectLog) {
            Long leaderId = leaderProjectLog.getLeaderId();
            if (list.indexOf(leaderId) == -1) { //不在则删除
                leaderProjectLogRepository.deleteById(leaderProjectLog.getId());
            } else {
                repeatlist.add(leaderId);
            }
        }
        list = getDifferenceSet(list, repeatlist);
        for (Long ids : list) {
            //在新增新的产业龙头
            LeaderProjectLog leaderProjectLog = new LeaderProjectLog();
            leaderProjectLog.setProjectId(project_id);
            leaderProjectLog.setLeaderId(ids);
            leaderProjectLog.setRelationTime(new Timestamp(new Date().getTime()));
            leaderProjectLog.setProjectLevel(optionalProject.get().getLevel());
            leaderProjectLogRepository.save(leaderProjectLog);
        }
    }

    public Map<String, Object> getLeaderProjectByLoginUser(Pageable pageable) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Page<Project> page = projectRepository.findAllByLeaderUser(userId, pageable);
        return PageUtil.toPage(page);
    }

    public List<Leader> getLeaderByProjectId(String projectId) {
        List<Leader> leader_list = new ArrayList<Leader>();
        List<LeaderProjectLog> list = leaderProjectLogRepository.findByProjectId(projectId);
        if (list == null) {
            throw new BadRequestException("产业龙头评分表项目未找到");
        }
        for (int i = 0; i < list.size(); i++) {
            LeaderProjectLog leaderProjectLog = list.get(i);
            Long leaderId = leaderProjectLog.getLeaderId();
            Optional<Leader> res = leaderRepository.findById(leaderId);
            if (res.isPresent()){
                leader_list.add(res.get());
            }
        }
        return leader_list;
    }

    public Map<String, Object> getProjectByLoginUser(Pageable pageable) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Page<Project> page = projectRepository.findAllByLeaderUser(userId, pageable);
        return PageUtil.toPage(page);
    }

    public void expertRating(ProjectExpertScoreDto projectExpertScoreDto) {
        BigDecimal score = projectExpertScoreDto.getScore();
        String projectId = projectExpertScoreDto.getProjectId();
        if (score == null) {
            throw new BadRequestException("评分为null");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        Optional<Project> optionalProject = projectRepository.findById(projectId);
        if (optionalProject.isEmpty()) {
            throw new BadRequestException("项目未找到");
        }
        Leader leader = leaderRepository.findByUserId(userId);
        if (leader == null) {
            throw new BadRequestException("未找到产业龙头专家");
        }
        Long expertId = leader.getId();
        //专家评分只能查找当前阶段level进行评分
        List<LeaderProjectLog> list = leaderProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expertId, projectId, optionalProject.get().getLevel());
        if (list == null || list.size() != 1) {
            throw new BadRequestException("产业龙头专家未分配指定项目");
        }
        LeaderProjectLog leaderProjectLog = list.get(0);
        leaderProjectLog.setScore(score);
        leaderProjectLog.setScoreTime(new Date());
        leaderProjectLog.setAdvice(projectExpertScoreDto.getAdvice());
        leaderProjectLogRepository.save(leaderProjectLog);
    }

    public ProjectDto getProjectScoreByProjectId(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        List<LeaderProjectLog> list = leaderProjectLogRepository.findByProjectId(projectId);
        projectDto.setLeaderScoreSituation(list);
        return projectDto;
    }

    public ProjectDto getProjectScoreByProjectIdSiftLevel(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        List<LeaderProjectLog> list1 = leaderProjectLogRepository.findByProjectIdProjectLevel(projectId, 1);
        projectDto.setListLeaderLevel1(list1);
        List<LeaderProjectLog> list2 = leaderProjectLogRepository.findByProjectIdProjectLevel(projectId, 2);
        projectDto.setListLeaderLevel2(list2);
        List<LeaderProjectLog> list3 = leaderProjectLogRepository.findByProjectIdProjectLevel(projectId, 3);
        projectDto.setListLeaderLevel3(list3);
        return projectDto;
    }
    public boolean getIsScoreByProjectId(String projectId) {
        Optional<Project> optionalProject = projectRepository.findById(projectId);
        if (optionalProject.isEmpty()) {
            throw new BadRequestException("项目未找到");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        Leader expert = leaderRepository.findByUserId(userId);
        if (expert == null) {
            throw new BadRequestException("产业龙头专家未找到");
        }
        List<LeaderProjectLog> list = leaderProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, optionalProject.get().getLevel());
        if (list != null && list.size() == 1) {
            LeaderProjectLog leaderProjectLog = list.get(0);
            if (leaderProjectLog != null) {
                BigDecimal score = leaderProjectLog.getScore();
                if (score != null) {
                    return true;
                }
            }
        }
        return false;
    }

    public ProjectDto getByProjectIdAndLoginUser(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        Leader expert = leaderRepository.findByUserId(userId);
        if (expert == null) {
            throw new BadRequestException("产业龙头专家未找到");
        }
        List<LeaderProjectLog> list = leaderProjectLogRepository.findByExpertIdAndProjectId(expert.getId(), projectId);
        projectDto.setLeaderScoreSituation(list);
        return projectDto;
    }

    public ProjectDto getByProjectIdAndLoginUserSiftLevel(String projectId) {
        ProjectDto projectDto = projectService.findById(projectId);
        if (projectDto == null) {
            throw new BadRequestException("项目未找到");
        }
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        Leader expert = leaderRepository.findByUserId(userId);
        if (expert == null) {
            throw new BadRequestException("产业龙头专家未找到");
        }
        List<LeaderProjectLog> list1 = leaderProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, 1);
        projectDto.setListLeaderLevel1(list1);
        List<LeaderProjectLog> list2 = leaderProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, 2);
        projectDto.setListLeaderLevel2(list2);
        List<LeaderProjectLog> list3 = leaderProjectLogRepository.findByExpertIdAndProjectIdWithLevel(expert.getId(), projectId, 3);
        projectDto.setListLeaderLevel3(list3);
        return projectDto;
    }
}